#include"fs.h"
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

static char zeros[BLOCK_SIZE];
static char aBlock[BLOCK_SIZE];
statis superblock sb;
int in;
u32 next_inode;
u32 next_zone;

//write a block to disk
void write_block(block_t n,char block[BLOCK_SIZE]) {
  if(lseek(in,(off_t)n * BLOCK_SIZE, SEEK_SET)==-1) {
    printf("write_block - Error: couldn't seek to block %d\n",n);
    exit(-1);
  }
  if(write(in,block,BLOCK_SIZE)!=BLOCK_SIZE) {
    printf("write_block - error: couldn't write to block %d\n",n);
    exit(-1);
  }
}

//read a block from a disk
void read_block(block_t n,char block[BLOCK_SIZE]) {
  if(lseek(in,(off_t)n * BLOCK_SIZE, SEEK_SET)==-1) {
    printf("read_block - Error: couldn't seek to block %d\n",n);
    exit(-1);
  }
  if(read(in,block,BLOCK_SIZE)!=BLOCK_SIZE) {
    printf("read_block - error: couldn't read block %d\n",n);
    exit(-1);
  }
}

//allocate a inode
int allocate_inode() {
  u32 inode_nr = sb.number_of_inodes;
  u32 imap_size = sb.size_imap_blocks;
  u32 first_imap_block = 1; 
  u32 onebyte;

  int i;
  int j;
  int k;

  //(1) check if there are any available inode
  for(i=0;i<imap_size;i++) {
    //for each block
    read_block(i+first_imap_block,aBlock);
    for(j=0;j<BLOCK_SIZE;j++) {
      if(i==imap_size-1) { //we are on the last block. need to be carefull
      }
      //get one byte
      onebyte = aBlock[j];
      
					       
    }
  }
  //(2) set a bit in the ibitmap

  //(3) write inode



}


int main(int argc,char* argv[]) {
  u32 number_inodes;
  u32 temp;
  u32 mapsize;
  u32 mapsize_blocks;
  u32 i;

  struct stat buf;

  //(1) open file
  in = open(argv[1],O_WRONLY);
  number_inodes = atoi(argv[2]);

  //(2) work out statistics
  fstat(in,&buf);

  //(3) write superblock
  sb.block_size = BLOCK_SIZE;
  sb.blocks_per_zone = 1;
  sb.total_blocks = buf.st_size/BLOCK_SIZE;
  sb.number_of_inodes = number_inodes;

   /*i-node bitmap size*/
  sb.size_imap_blocks = (number_inodes/8)+1;
  /*i-node space blocks*/
  temp = (number_inodes * SIZE_INODE) / BLOCK_SIZE;
  if((number_inodes*SIZE_INODE)%BLOCK_SIZE!=0) temp++;
  sb.inodes_space_blocks = temp;
 
  /*zone bitmap size*/
  // remainaing blocks
  temp = sb.total_blocks - 1; //super block
  temp -= sb.size_imap_blocks; //inode bit-map
  temp -= sb.inodes_space_blocks; //inode space
  
  //printf("remaining block size for data %d\n",temp);
  mapsize = temp/8; 
  // printf("mapsize is %d\n",mapsize);
  mapsize_blocks = mapsize/BLOCK_SIZE;
  if((mapsize%BLOCK_SIZE)!=0) mapsize_blocks++;
  //printf("mapsize is %d\n",mapsize_blocks);
  sb.size_zmap_blocks = mapsize_blocks;
  sb.data_space_blocks = sb.total_blocks -1 - sb.size_imap_blocks - sb.inodes_space_blocks - sb.size_zmap_blocks;

  sb.first_inode_block = size_imap_blocks+size_zmap_bocks;
  sb.first_data_block = size_imap_blocks+size_zmap_blocks + inoes_space_blocks;

  printf("(1) Formatting image file by writing %d empty blocks..\n",sb.total_blocks);
   //erase the everthing on the disk//
  memset(&zeros,0,BLOCK_SIZE);
  memset(&aBlock,0,BLOCK_SIZE);

  for(i=0;i<sb.total_blocks;i++) {
    write_block(i,zeros);
  }

  //do the integrity check
  printf("(2) Writing super block information..\n");
  printf("Super block: %d\n",1);
  printf("imap blocks: %d\n",sb.size_imap_blocks);
  printf("zmap_blocks: %d\n",sb.size_zmap_blocks);
  printf("inodes_space_blocks: %d\n",sb.inodes_space_blocks);
  printf("data_space_blocks: %d\n",sb.data_space_blocks);
  printf("sum: %d\n",1 + sb.size_imap_blocks + sb.size_zmap_blocks + sb.inodes_space_blocks + sb.data_space_blocks);
  printf("Number of inodes: %d\n", sb.number_of_inodes);
  //printf("total blocks %d\n",sb.total_blocks); 

  //writing superblock at 0.
  memcpy(aBlock,&sb,sizeof(sb));
  write_block(0,aBlock);

  //allocate root inode
  
  next_inode= 0;
  

  
}
